#include <iostream>
#include <memory>
using namespace std;

class XData
{
public:
    XData(){cout << "Create XData" << endl;}
    ~XData(){cout << "Drop XData" << endl;}
};

void DelData(XData* p)
{
    cout << "call DelData" << endl;
    delete p;
}

int main(int argc, char const *argv[])
{
    // 1. 初步使用
    shared_ptr<int> sp1(new int);
    shared_ptr<int []> sp2(new int[1024]);
    *sp1 = 10;
    sp2[0] = 10;
    auto d1 = sp1.get();
    auto sp3 = make_shared<XData>();
    cout << "sp3.use_count() = " << sp3.use_count() << endl;

    // 2. 可复制构造和赋值
    auto sp4 = sp3;
    cout << "sp3.use_count() = " << sp3.use_count() << endl;
    cout << "sp4.use_count() = " << sp4.use_count() << endl;
    auto sp5 = make_shared<XData>();
    sp4 = sp5;
    cout << "sp3.use_count() = " << sp3.use_count() << endl;

    // 3. 定制删除函数
    shared_ptr<XData> sp7(new XData, DelData);
    shared_ptr<XData> sp8(new XData, [](auto p) {
        cout << "call delete lambda" << endl;
        delete p;
        });

    // 4. 循环引用问题
    class B;
    class A
    {
    public:
        A(){cout << "Creat A" << endl;}
        ~A() {cout << "Drop A" << endl;}
        shared_ptr<B> b1;
    };
    class B
    {
    public:
        B(){cout << "Creat B" << endl;}
        ~B() {cout << "Drop B" << endl;}
        shared_ptr<A> a1;
    };
    {
        auto a = make_shared<A>();
        auto b = make_shared<B>();
        a->b1 = b;
        cout << "b.use_count = " << b.use_count() << endl;
        b->a1 = a;
        cout << "a.use_count = " << a.use_count() << endl;
    }

    cout << "test 02" << endl;
    return 0;
}
